home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / daemons / timed / candidate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-12-23  |  3.1 KB  |  127 lines

  1. /*
  2.  * Copyright (c) 1983 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms are permitted
  6.  * provided that this notice is preserved and that due credit is given
  7.  * to the University of California at Berkeley. The name of the University
  8.  * may not be used to endorse or promote products derived from this
  9.  * software without specific prior written permission. This software
  10.  * is provided ``as is'' without express or implied warranty.
  11.  */
  12.  
  13. #ifndef lint
  14. static char sccsid[] = "@(#)candidate.c    2.4 (Berkeley) 12/23/87";
  15. #endif /* not lint */
  16.  
  17. #include "globals.h"
  18. #include <protocols/timed.h>
  19.  
  20. #define ELECTIONWAIT    3    /* seconds */
  21.  
  22. /*
  23.  * `election' candidates a host as master: it is called by a slave 
  24.  * which runs with the -M option set when its election timeout expires. 
  25.  * Note the conservative approach: if a new timed comes up, or another
  26.  * candidate sends an election request, the candidature is withdrawn.
  27.  */
  28.  
  29. election(net)
  30. struct netinfo *net;
  31. {
  32.     int ret;
  33.     struct tsp *resp, msg, *readmsg();
  34.     struct timeval wait;
  35.     struct tsp *answer, *acksend();
  36.     long casual();
  37.     struct sockaddr_in server;
  38.  
  39.     syslog(LOG_INFO, "THIS MACHINE IS A CANDIDATE");
  40.     if (trace) {
  41.         fprintf(fd, "THIS MACHINE IS A CANDIDATE\n");
  42.     }
  43.  
  44.     ret = MASTER;
  45.     slvcount = 1;
  46.  
  47.     msg.tsp_type = TSP_ELECTION;
  48.     msg.tsp_vers = TSPVERSION;
  49.     (void)strcpy(msg.tsp_name, hostname);
  50.     bytenetorder(&msg);
  51.     if (sendto(sock, (char *)&msg, sizeof(struct tsp), 0, &net->dest_addr,
  52.         sizeof(struct sockaddr_in)) < 0) {
  53.         syslog(LOG_ERR, "sendto: %m");
  54.         exit(1);
  55.     }
  56.  
  57.     do {
  58.         wait.tv_sec = ELECTIONWAIT;
  59.         wait.tv_usec = 0;
  60.         resp = readmsg(TSP_ANY, (char *)ANYADDR, &wait, net);
  61.         if (resp != NULL) {
  62.             switch (resp->tsp_type) {
  63.  
  64.             case TSP_ACCEPT:
  65.                 (void) addmach(resp->tsp_name, &from);
  66.                 break;
  67.  
  68.             case TSP_MASTERUP:
  69.             case TSP_MASTERREQ:
  70.                 /*
  71.                  * If a timedaemon is coming up at the same time,
  72.                  * give up the candidature: it will be the master.
  73.                  */
  74.                 ret = SLAVE;
  75.                 break;
  76.  
  77.             case TSP_QUIT:
  78.             case TSP_REFUSE:
  79.                 /*
  80.                  * Collision: change value of election timer 
  81.                  * using exponential backoff.
  82.                  * The value of timer will be recomputed (in slave.c)
  83.                  * using the original interval when election will 
  84.                  * be successfully completed.
  85.                  */
  86.                 backoff *= 2;
  87.                 delay2 = casual((long)MINTOUT, 
  88.                             (long)(MAXTOUT * backoff));
  89.                 ret = SLAVE;
  90.                 break;
  91.  
  92.             case TSP_ELECTION:
  93.                 /* no master for another round */
  94.                 msg.tsp_type = TSP_REFUSE;
  95.                 (void)strcpy(msg.tsp_name, hostname);
  96.                 server = from;
  97.                 answer = acksend(&msg, &server, resp->tsp_name,
  98.                     TSP_ACK, (struct netinfo *)NULL);
  99.                 if (answer == NULL) {
  100.                     syslog(LOG_ERR, "error in election");
  101.                 } else {
  102.                     (void) addmach(resp->tsp_name, &from);
  103.                 }
  104.                 break;
  105.  
  106.             case TSP_SLAVEUP:
  107.                 (void) addmach(resp->tsp_name, &from);
  108.                 break;
  109.  
  110.             case TSP_SETDATE:
  111.             case TSP_SETDATEREQ:
  112.                 break;
  113.  
  114.             default:
  115.                 if (trace) {
  116.                     fprintf(fd, "candidate: ");
  117.                     print(resp, &from);
  118.                 }
  119.                 break;
  120.             }
  121.         } else {
  122.             break;
  123.         }
  124.     } while (ret == MASTER);
  125.     return(ret);
  126. }
  127.